package protocol

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"gitee.com/go-course/go8/projects/vblog/api/conf"
	"github.com/gin-gonic/gin"
	"github.com/infraboard/mcube/logger"
	"github.com/infraboard/mcube/logger/zap"

	"gitee.com/go-course/go8/projects/vblog/api/apps"
	_ "gitee.com/go-course/go8/projects/vblog/api/apps/all"
)

// HTTP 服务, 需要有简单的地址和端口, 冲全局配置种获取Server监听参数
func NewHTTP() *HTTP {
	r := gin.Default()
	return &HTTP{
		log:    zap.L().Named("server.http"),
		router: r,
		server: &http.Server{
			ReadHeaderTimeout: 60 * time.Second,
			ReadTimeout:       60 * time.Second,
			WriteTimeout:      60 * time.Second,
			IdleTimeout:       60 * time.Second,
			MaxHeaderBytes:    1 << 20, // 1M
			// 出来HTTP 协议的逻辑, HTTP 中间件, 是一个路由(框架,Gin, ...)与处理(自己)
			Handler: r,
			Addr:    conf.C().App.HTTP.Addr(),
		},
	}
}

// HTTP 服务对象
type HTTP struct {
	router *gin.Engine
	server *http.Server
	log    logger.Logger
}

func (h *HTTP) Start() error {
	if err := apps.Init(); err != nil {
		return err
	}

	v1 := h.router.Group("/vblog/api/v1")
	apps.InitHttpService(v1)

	// 打印下日志
	h.log.Infof("http server serve on: %s", h.server.Addr)

	if err := h.server.ListenAndServe(); err != nil {
		// 处理正常退出情况
		if err == http.ErrServerClosed {
			return nil
		}

		return fmt.Errorf("server ListenAndServe error, %s", err)
	}

	return nil
}

func (h *HTTP) Stop(ctx context.Context) {
	h.log.Infof("server garceful shutdown ...")
	// HTTP Server 优雅关闭
	// 支持ctx, 10分 请求都没退出, 做超时设置
	if err := h.server.Shutdown(ctx); err != nil {
		h.log.Warnf("shutdown error, %s", err)
	} else {
		h.log.Infof("server garceful shutdown ok")
	}
}
